package com.zeroes.cons;


import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.IntBuffer;
import android.content.Context;
import org.zeroes.common_prelude.*;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.opengl.GLES20;
//import playn.text.*;
public class ZSTexture2D {

	private int texID;
	public static final int kMaxTextureSize = 1024;
	public static final int FONT = 10;
	public static final int STREAM = 11;
	public static final int IMAGEBYTES = 12;
	public static final int FORMATEDTEXT = 13;
	public int source=0;
	private int height;
	private int width;
	private byte[] _imagedata;
	private InputStream _is;
	private String _text;
	private String _fontname;
	private float _fontSize;
	private TextFormat _format;
	private boolean fttr=true;
    public enum TextAlignment {
        LEFT,
        CENTER,
        RIGHT
    }
    private TextAlignment alignment;
	public  ZSTexture2D(InputStream is){
		this.source=ZSTexture2D.STREAM;
		_is=is;
		   this.initfromstream(is);
	}
	
	
	public ZSTexture2D(byte[] imagedata){
		this.source=ZSTexture2D.IMAGEBYTES;
		_imagedata=imagedata;
		this.initfromimagedata(imagedata);
		 
	}
	
	public int texID(){
		return this.texID;
	}
	public int width(){
		return this.width;
	}
	public int height(){
		return this.height;
	}
	public ZSTexture2D(String text, String fontname, float fontSize){
		this.source=ZSTexture2D.FONT;
		_text=text;
		_fontname=fontname;
		_fontSize=fontSize;
		initWithText(text,fontname,fontSize);
	}
	 public void initWithText(String text, String fontname, float fontSize) {
	    	initWithText(text, calculateTextSize(text, fontname, fontSize),
	                TextAlignment.CENTER, fontname, fontSize);
	    }

	    private static CGSize calculateTextSize(String text, String fontname, float fontSize) {
//	        Typeface typeface = Typeface.create(fontname, Typeface.NORMAL);
	        Typeface typeface;
	        Context _ctx = ZSGameManager.AskMe().ctx;
	    	try{
	    		typeface = Typeface.createFromAsset(_ctx.getAssets(), fontname);
	    	} catch (Exception e) {
	    		typeface = Typeface.create(fontname, Typeface.NORMAL);
			}

	        Paint textPaint = new Paint();
	        textPaint.setTypeface(typeface);
	        textPaint.setTextSize(fontSize);
	        textPaint.setAntiAlias(true);

	        int ascent = (int) Math.ceil(-textPaint.ascent());  // Paint.ascent is negative, so negate it
	        int descent = (int) Math.ceil(textPaint.descent());
	        int measuredTextWidth = (int) Math.ceil(textPaint.measureText(text));

	        return CGSize.make(measuredTextWidth, ascent + descent);
	    }

	    private static int toPow2(int v) {
	        if ((v != 1) && (v & (v - 1)) != 0) {
	            int i = 1;
	            while (i < v)
	                i *= 2;
	            v = i;
	        }
	        if (v > ZSTexture2D.kMaxTextureSize) {
	        	v = ZSTexture2D.kMaxTextureSize;
	        }
	        return v;
	    }

	    /** Initializes a texture from a string with dimensions, alignment, font name and font size */
	    public void initWithText(String text, CGSize dimensions, TextAlignment alignment, String fontname, float fontSize) {
	    	//Typeface.create(fontname, Typeface.NORMAL);
	    	Typeface typeface;
	    	Context _ctx = ZSGameManager.AskMe().ctx;
	    	try{
	    		typeface = Typeface.createFromAsset(_ctx.getAssets(), fontname);
	    	} catch (Exception e) {
	    		typeface = Typeface.create(fontname, Typeface.NORMAL);
			}

	        Paint textPaint = new Paint();
	        textPaint.setTypeface(typeface);
	        textPaint.setTextSize(fontSize);
	        textPaint.setAntiAlias(true);
	        textPaint.setARGB(255, 255, 0, 0);
	        int ascent = (int) Math.ceil(-textPaint.ascent());  // Paint.ascent is negative, so negate it
	        int descent = (int) Math.ceil(textPaint.descent());
	        int measuredTextWidth = (int) Math.ceil(textPaint.measureText(text));


	        int textWidth = measuredTextWidth;
	        int textHeight = ascent + descent;

	        int width = toPow2((int)dimensions.width);
	        int height = toPow2((int) dimensions.height);
	        this.width=width;
	        this.height=height;
	        Bitmap.Config config = Bitmap.Config.ARGB_8888;
	        Bitmap bitmap = Bitmap.createBitmap(width, height, config);
	        Canvas canvas = new Canvas(bitmap);
	        bitmap.eraseColor(Color.TRANSPARENT);

	        int centerOffsetHeight = ((int) dimensions.height - textHeight) / 2;
	        int centerOffsetWidth = ((int) dimensions.width - textWidth) / 2;

	        switch (alignment) {
	            case LEFT:
	                centerOffsetWidth = 0;
	                break;
	            case CENTER:
	                //centerOffsetWidth = (effectiveTextWidth - textWidth) / 2;
	                break;
	            case RIGHT:
	                centerOffsetWidth = (int) dimensions.width - textWidth;
	                break;
	        }

	        canvas.drawText(text,
	                centerOffsetWidth,
	                ascent + centerOffsetHeight,
	                textPaint);
	        int[] textureId = new int[1];    
	    ByteBuffer byteBuffer = ByteBuffer.allocateDirect(bitmap.getWidth() * bitmap.getHeight() * 4);
	  //  byteBuffer.order(ByteOrder.BIG_ENDIAN);
	    /*IntBuffer ib = byteBuffer.asIntBuffer();
	    
	    int[] pixels = new int[bitmap.getWidth() * bitmap.getHeight()];
	    bitmap.getPixels(pixels, 0, bitmap.getWidth(), 0, 0, bitmap.getWidth(), bitmap.getHeight());
	    for(int i=0; i<pixels.length; i++){
	    	ib.put(pixels[i] << 8 | pixels[i] >>> 24);

	    }

	    bitmap.recycle();*/
	    bitmap.copyPixelsToBuffer(byteBuffer);
	    byteBuffer.position(0);
	    if(this.fttr){
	    GLES20.glGenTextures ( 1, textureId, 0 );
	    GLES20.glBindTexture ( GLES20.GL_TEXTURE_2D, textureId[0] );
	    texID=textureId[0];
	    fttr=false;
	    }
	    else
	    {
	    	GLES20.glBindTexture ( GLES20.GL_TEXTURE_2D, this.texID );
	    }
	    
	    
	    GLES20.glTexImage2D ( GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, bitmap.getWidth(), bitmap.getHeight(), 0,
	    GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE,byteBuffer );
	    
	    GLES20.glTexParameteri ( GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR );
	    GLES20.glTexParameteri ( GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR );
	    GLES20.glTexParameteri ( GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE );
	    GLES20.glTexParameteri ( GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE );	
	
	    
	      //  init(bitmap, dimensions, dimensions);
	    }

	public ZSTexture2D (){
		
		this.source=ZSTexture2D.FORMATEDTEXT;
	}
	
	public ZSTexture2D (CGSize size){
		
		this.width=(int)size.width;
		this.height=(int)size.height;
	}
	
	public void drawFormatedText(String text,TextFormat format){
		this._text=text;
		this._format=format;
		AndroidTextLayout textlayout = new AndroidTextLayout(text,format);
		this.width=(int)textlayout.width();
		this.height=(int)textlayout.height();
		Bitmap.Config config = Bitmap.Config.ARGB_8888;
        Bitmap bitmap = Bitmap.createBitmap(width, height, config);
        Canvas canvas = new Canvas(bitmap);
        bitmap.eraseColor(Color.TRANSPARENT);
        
        textlayout.draw(canvas, 0, 0);
        int[] textureId = new int[1];    
	    ByteBuffer byteBuffer = ByteBuffer.allocateDirect(bitmap.getWidth() * bitmap.getHeight() * 4);
	  
	    bitmap.copyPixelsToBuffer(byteBuffer);
	    bitmap.recycle();
	    byteBuffer.position(0);
	    GLES20.glGenTextures ( 1, textureId, 0 );
	    GLES20.glBindTexture ( GLES20.GL_TEXTURE_2D, textureId[0] );
	    
	    GLES20.glTexImage2D ( GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, bitmap.getWidth(), bitmap.getHeight(), 0,
	    GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE,byteBuffer );
	    
	    GLES20.glTexParameteri ( GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR );
	    GLES20.glTexParameteri ( GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR );
	    GLES20.glTexParameteri ( GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE );
	    GLES20.glTexParameteri ( GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE );	
	
	    texID=textureId[0];
	}
	
	private void initfromimagedata(byte[] data){
		int[] textureId = new int[1];
		 Bitmap bitmap;
		    
			
			bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
			
		    ByteBuffer byteBuffer = ByteBuffer.allocateDirect(bitmap.getWidth() * bitmap.getHeight() * 4);
		    byteBuffer.order(ByteOrder.BIG_ENDIAN);
		    IntBuffer ib = byteBuffer.asIntBuffer();
		    
		    int[] pixels = new int[bitmap.getWidth() * bitmap.getHeight()];
		    bitmap.getPixels(pixels, 0, bitmap.getWidth(), 0, 0, bitmap.getWidth(), bitmap.getHeight());
		    for(int i=0; i<pixels.length; i++){
		    	ib.put(pixels[i] << 8 | pixels[i] >>> 24);

		    }
		    height=bitmap.getHeight();
		    width=bitmap.getWidth();
		    bitmap.recycle();
		    
	   
	    
	    byteBuffer.position(0);
	    GLES20.glGenTextures ( 1, textureId, 0 );
	    GLES20.glBindTexture ( GLES20.GL_TEXTURE_2D, textureId[0] );
	    
	    GLES20.glTexImage2D ( GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, width, height, 0,
	    GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE,byteBuffer );
	    
	    GLES20.glTexParameteri ( GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR );
	    GLES20.glTexParameteri ( GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR );
	    GLES20.glTexParameteri ( GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE );
	    GLES20.glTexParameteri ( GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE );	
	
	    texID=textureId[0];
	}
	
	private void initfromstream(InputStream s){
		int[] textureId = new int[1];
		   BitmapFactory.Options opts = new BitmapFactory.Options();
		   //opts.inScaled = false;
		    Bitmap bitmap;
		    
		
				bitmap = BitmapFactory.decodeStream(s,null,opts);

			
			    
		    ByteBuffer byteBuffer = ByteBuffer.allocateDirect(bitmap.getWidth() * bitmap.getHeight() * 4);
		    byteBuffer.order(ByteOrder.BIG_ENDIAN);
		    IntBuffer ib = byteBuffer.asIntBuffer();
		    
		    int[] pixels = new int[bitmap.getWidth() * bitmap.getHeight()];
		    bitmap.getPixels(pixels, 0, bitmap.getWidth(), 0, 0, bitmap.getWidth(), bitmap.getHeight());
		    for(int i=0; i<pixels.length; i++){
		    	ib.put(pixels[i] << 8 | pixels[i] >>> 24);

		    }
		    height=bitmap.getHeight();
		    width=bitmap.getWidth();
		    bitmap.recycle();
		    
		    byteBuffer.position(0);
		    GLES20.glGenTextures ( 1, textureId, 0 );
		    GLES20.glBindTexture ( GLES20.GL_TEXTURE_2D, textureId[0] );
		    
		    GLES20.glTexImage2D ( GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, bitmap.getWidth(), bitmap.getHeight(), 0,
		    GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE,byteBuffer );
		    
		    GLES20.glTexParameteri ( GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR );
		    GLES20.glTexParameteri ( GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR );
		    GLES20.glTexParameteri ( GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE );
		    GLES20.glTexParameteri ( GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE );	
		
		    texID=textureId[0];
		    	
		
	}
	
	public void reload(){
		
		switch(source){
		case ZSTexture2D.FONT :
			initWithText(_text,_fontname,_fontSize);
			break;
		case ZSTexture2D.IMAGEBYTES :
			this.initfromimagedata(_imagedata);
			break;
		case ZSTexture2D.STREAM :
			this.initfromstream(_is);
			break;
		case ZSTexture2D.FORMATEDTEXT :
			this.drawFormatedText(_text, _format);
			break;
		}
	}
}
